/* [gridNess] */
/*
 * This software is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
 *
 *	>site : http://www.nessy.com.ar
 *	>author : Francisco Rosales <francisco.rosales@gmail.com>
 *	@id = {string}
 * 		: optional (default = 'NessGrid')
 *		: id of the main table (<table id={id} ...)
 *	@containerDIV = {string}
 *		: obligatory
 *		: div that while displayed the table
 *	@dataTable = {cols:[{Ness.Grid.Pojo.Column}],rows:[{Ness.Grid.Pojo.Row}]}
 *		: managed by application
 *		: all data
 *	@onClick = function({rowObj}){}
 *		: optional (default = function(){})
 *		: click event function of the row with row object argument
 *	@colId = {number}
 *		: optional (default = 0)
 *		: column number that help to the Ness system to manage data
 *
 *	<static> Ness.Grid.Pojo.Column : { title:{string}, width:{number} }
 *	<static> Ness.Grid.Pojo.Row : { data:{string}, style:{string} }
 *	<static> Ness.Grid.Util.Convert2RowData : Convert simple array of {string} in array of {Ness.Grid.Pojo.Row}
 *
 *	<>insertRow(Ness.Grid.Pojo.Row)
 *		: insert row
 *	<>updateRow(Ness.Grid.Pojo.Row)
 *		: update row
 *	<>deleteRow(Ness.Grid.Pojo.Row)
 *		: delete row with row object argument
 *	<>deleteRow({number})
 *		: delete row with row index argument (position of dataTable.rows)
 *	<>selekRow()
 *		: select row
 *	<>selekRow({number})
 *		: select row with row index argument
 *	<>selekRow({[array of Ness.Grid.Pojo.Row]})
 *		: select row with array of a row object
 *	<>clearRowSelek()
 *		: clear row selected
 *	<>getRowIndexById({number})
 *		: get row index {number} by passing id argument (colId numner)
 *	<>deleteAllRows()
 *		: delete all data in dataTable and display empty table
 *	> ! orderBy not finished, only order by DESC
 *	<>orderBy()
 *
 */

var Ness = {
  Version: '20070727-1'
}
Ness.Elements = {
	lista: [],
	agregar: function(elem){ this.lista.push(elem); },
	getByID: function(idElem){
		var ret;
		for(var i=0; i<this.lista.length; i++){
			if(this.lista[i].id==idElem){ ret = this.lista[i]; }
		}
		return ret;
	}
}
Ness.Grid = function(config){
	this.id = "NessGrid";
	this.containerDIV = "";
	this.dataTable = {};
	this.onClick = function(){};
	this.colId = 0;
	this.mouseOverOut = true;
	this.columnOrder = true;
	if(arguments.length > 0) this.init(config);
	Ness.Elements.agregar(this);
}
Ness.Grid.prototype.init = function(config) {
	for(var cada in config){
		if(this[cada]!=undefined){
			this[cada] = config[cada];
		}
	}
};
Ness.Grid.prototype.display = function(){
	var gHTML = "\
			<table id='{id}' class='NessGrid' width='{anchoTotal}' cellspacing='1'>\
			{anchoColumnas}\
			<tr>\
				{columnas}\
			</tr>\
				{lineas}\
			</table>\
			";
	gHTML = gHTML.replace("{id}",this.id);
	gHTML = gHTML.replace("{anchoTotal}",this._getAnchoTotal());
	gHTML = gHTML.replace("{anchoColumnas}",this._getAnchos2HTML());
	gHTML = gHTML.replace("{columnas}",this._getTitulo2HTML());
	gHTML = gHTML.replace("{lineas}",this._getRows2HTML());
	$(this.containerDIV).innerHTML = gHTML;
	$(this.containerDIV).style.display = "";
}
Ness.Grid.prototype._getAnchoTotal = function(){
	var total = 0;
	var cols = this.dataTable.cols;
	for(var i=0; i<cols.length; i++){
		var nro = Number(cols[i].width);
		if(!isNaN(nro)){
			total += nro;
		}
	}
	return total;
}
Ness.Grid.prototype._getAnchos2HTML = function(){
	var cols = this.dataTable.cols;
	var tHTML = "";
	for(var i=0; i<cols.length; i++){
		var txt = "<col width='{width}'>";
		txt = txt.replace("{width}",cols[i].width);
		tHTML += txt;
	}
	return tHTML;
}
Ness.Grid.prototype._getRows2HTML = function(){
	var lineas = this.dataTable.rows;
	var tHTML = "";
	for(var i=0; i<lineas.length; i++){
		var txt = "\
			<tr height='22'>\
				{valores}\
			</tr>\
			";
		txt = txt.split("{valores}").join(this._getValores2HTML(lineas[i],i));
		tHTML += txt;
	}
	return tHTML;
}
Ness.Grid.prototype._getRowName = function(rowIndex){
	return "rowNess"+rowIndex;
}
Ness.Grid.prototype._getValores2HTML = function(unaLinea,rowIndex){
	var tHTML = "";
	var cantidad = this.dataTable.cols.length;
	for(var i=0; i<cantidad; i++){
		var classOver = "";
		var classOut = "";
		var txt = "\
					<td class='{tdClass}' id='{rowId}' {estilo} \
					{mouseOverOut} \
					onclick='Ness.Grid.EventClick(\"{idGrid}\",{rowIndex})' >\
					<span style='width:{width}px;overflow:hidden'>{valor}</span>\
					</td>\
				";
		var mouseOverOutTXT = "";
		if(this.mouseOverOut){
			mouseOverOutTXT = "\
					onmouseover='Ness.Grid.EventMouseOver(this)' \
					onmouseout='Ness.Grid.EventMouseOut(this)' \
					";
		}
		var valor = unaLinea[i].data;
		var estilo = (unaLinea[i].style!=undefined)?"style='"+unaLinea[i].style+"'":"";
		txt = txt.replace("{mouseOverOut}",mouseOverOutTXT);
		txt = txt.replace("{idGrid}",this.id);
		txt = txt.replace("{rowIndex}",rowIndex);
		txt = txt.replace("{valor}",valor);
		txt = txt.replace("{estilo}",estilo);
		txt = txt.replace("{width}",this.dataTable.cols[i].width);
		var tdClass = (rowIndex%2==1)?"nessRowOdd":"nessRowEven";
		if(i==this.colId){ tdClass = "nessColID"; }
		txt = txt.replace("{tdClass}",tdClass);
		txt = txt.replace("{rowId}",this._getRowName(rowIndex));
		tHTML += txt;
	}
	return tHTML;
}
Ness.Grid.prototype._getTitulo2HTML = function(){
	var columnas = this.dataTable.cols;
	var tHTML = "";
	for(var i=0; i<columnas.length; i++){
		var titulo = columnas[i].title;
		var thClass = (i==0)?"nessTHeadID":"";
		var txt = "<th class='{thClass}' {thOnClick}>{titulo} <img src='gridNess/i/flecha_orden_desc.gif' width='7' height='5'></th>";
		var thOnClick = "";
		if(this.columnOrder){
			thOnClick = "onclick='Ness.Grid.EventOrder(\"{idGrid}\",{colIndex})'";
			thClass += " nessTHOrder";
		}
		txt = txt.replace("{thOnClick}",thOnClick);
		txt = txt.replace("{colIndex}",i);
		txt = txt.replace("{idGrid}",this.id);
		txt = txt.replace("{titulo}",titulo);
		txt = txt.replace("{thClass}",thClass);
		tHTML += txt;
	}
	return tHTML;
}
Ness.Grid.EventMouseOver = function(elemento){
	var nodosTD = $A(elemento.parentNode.getElementsByTagName('td'));
	/*
	nodosTD.map(Element.extend).invoke('setClassName2Old','oldClass');
	nodosTD.map(Element.extend).invoke('addClassName','nessRowOver');
	*/
	var cant = nodosTD.length;
	for(var i=0; i<cant; i++){
		var nodoTD = nodosTD[i];
		nodoTD.oldClass = nodoTD.className;
		var classOver = "nessRowOver";
		if(nodoTD.className=="nessColID"){ classOver = "nessColIDOver"; }
		if(nodoTD.className!="nessColID"){
			nodoTD.className += " " + classOver;
		}
	}
}
Ness.Grid.EventOrder = function(idGrid,colIndex){
	var instancia = Ness.Elements.getByID(idGrid);
	instancia.orderBy(colIndex);
	instancia.selekCol(colIndex);
}
Ness.Grid.EventMouseOut = function(elemento){
	var nodosTD = $A(elemento.parentNode.getElementsByTagName('td'));
	nodosTD.map(Element.extend).invoke('removeClassName','nessRowOver');
}
Ness.Grid.EventClick = function(idGrid,rowIndex){
	var instancia = Ness.Elements.getByID(idGrid);
	var linea = instancia.dataTable.rows[rowIndex];
	instancia.onClick(linea);
	instancia.selekRow();
}
Ness.Grid.prototype.clearRowSelek = function(){
	$(this.id).getElementsByClassName('nessRowSelek').invoke('removeClassName','nessRowSelek');
}
Ness.Grid.prototype.selekRow = function(){ // arguments[0] -> rowIndex
	this.clearRowSelek();
	if (arguments[0]!=undefined){
		if (arguments[0] instanceof Object){
			var rowObj = arguments[0];
			var rowIndex = this.getRowIndexById(rowObj[this.colId].data);
		} else {
			var rowIndex = arguments[0];
		}
		var rowName = this._getRowName(rowIndex);
		var selekTDS = $A($(this.id).getElementsByTagName("td"));
		for(var i=0; i<selekTDS.length; i++){
			var selekTD = selekTDS[i];
			if(selekTD.id==rowName){ selekTD.addClassName('nessRowSelek'); }
		}
	} else {
		$(this.id).getElementsByClassName('nessRowOver').invoke('addClassName','nessRowSelek');
	}
}
Ness.Grid.prototype.updateRow = function(rowObj){
	var rowIndex = (arguments[1]!=undefined)?arguments[1]:-1;
	if(rowIndex==-1){
		rowIndex = this.getRowIndexById(rowObj[this.colId].data);
	}
	this.dataTable.rows[rowIndex] = rowObj;
	this.display();
}
Ness.Grid.prototype.insertRow = function(rowObj){
	var rowIndex = (arguments[1]!=undefined)?arguments[1]:-1;
	if(rowIndex==-1){
		this.dataTable.rows.push(rowObj);
	} else {
		this.dataTable.rows.splice(rowIndex, 0, rowObj);
	}
	this.display();
}
Ness.Grid.prototype.deleteRow = function(obj){
	if(typeof obj == "object"){
		this._deleteRow4Obj(obj);
	} else {
		this._deleteRow4RowIndex(obj);
	}
}
Ness.Grid.prototype._deleteRow4Obj = function(rowObj){
	var rowIndex = this.getRowIndexById(rowObj[this.colId].data);
	this._deleteRow4RowIndex(rowIndex);
}
Ness.Grid.prototype._deleteRow4RowIndex = function(rowIndex){
	this.dataTable.rows.splice(rowIndex,1);
	this.display();
}
Ness.Grid.prototype.deleteAllRows = function(obj){
	this.dataTable.rows = [];
	this.display();
}
Ness.Grid.prototype.getDataById = function(id){
	var ret;
	var rows = this.dataTable.rows;
	for(var i=0; i<rows.length; i++){
		if(rows[i][this.colId].data==id){ ret = rows[i]; }
	}
	return ret;
}
Ness.Grid.prototype.getRowIndexById = function(id){
	var ret;
	var rows = this.dataTable.rows;
	for(var i=0; i<rows.length; i++){
		if(rows[i][this.colId].data==id){ ret = i; }
	}
	return ret;
}
Ness.Grid.Util = {};
Ness.Grid.Util.Convert2RowData = function(arr){
	// [ {string},{string} ] -> [ {data:{string},style:{string}},{data:{string},style:{string}} ]
	var rows = [];
	for(var i=0; i<arr.length; i++){
		var rowObj = new Ness.Grid.Pojo.Row();
		var arrOne = arr[i];
		if(typeof arrOne == "string"){
			rowObj.data = arrOne;
		} else {
			for(var cada in arrOne){
				if(typeof arrOne[cada]!=undefined && rowObj[cada]!=undefined){
					rowObj[cada] = arrOne[cada];
				}
			}
		}
		rows.push(rowObj);
	}
	return rows;
}
Ness.Grid.Pojo = {};
Ness.Grid.Pojo.Column = function(){
	this.title = '';
	this.width = 0;
	this.type = 'string'; // string, number
}
Ness.Grid.Pojo.Row = function(){
	this.data = '';
	this.style = '';
}
Ness.Grid.Util.ConvertColum2Array = function(rows,col){
	var arr = [];
	for(var i=0; i<rows.length; i++){
		var colValue = rows[i][col].data;
		arr.push(colValue);
	}
	return arr;
}
Ness.Grid.prototype.orderBy = function(colSort){
	_colSort = colSort; //variable global
	var colType = this.dataTable.cols[_colSort].type;
	var row2order = this.dataTable.rows.clone();
	var sortFNC = this._sortNumberFunc;
	if(colType=="string"){
		sortFNC = this._sortStringFunc;
	}
	this.dataTable.rows = row2order.sort(sortFNC);
	this.display();
}
Ness.Grid.prototype._sortNumberFunc = function(a, b){
	return b[_colSort].data - a[_colSort].data;
}
Ness.Grid.prototype._sortStringFunc = function(a, b){
	var valor1 = a[_colSort].data;
	var valor2 = b[_colSort].data;
	if(valor1 > valor2)
		return 1
	if(valor1 < valor2)
		return -1
	return 0
} 
Ness.Grid.prototype.selekCol = function(colIndex){
	this.clearColSelek();
	var selekTHS = $A($(this.id).getElementsByTagName("th"));
	for(var i=0; i<selekTHS.length; i++){
		var selekTH = selekTHS[i];
		if(i==colIndex){ selekTH.addClassName('nessColSelek'); }
	}
}
Ness.Grid.prototype.clearColSelek = function(){
	$(this.id).getElementsByClassName('nessColSelek').invoke('removeClassName','nessColSelek');
}
